package com.atguigu.yeb.server.security;


import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author senior   和token有关的工具类
 * @create 2021-12-04 9:00
 */
@Component
public class JWTUtils {

    private static final String CLAIM_KEY_USERNAME = "sub";
    private static final String CLAIM_KEY_CREATED = "created";

    @Value("${jwt.secret}")
    private String secret;
    @Value("${jwt.expiration}")
    private Long expiration;

    /*
    根据负载生成JWT token
     */
    private String generateToken(Map<String,Object> param){
        return Jwts.builder()
                .setClaims(param)
                .setExpiration(generateExpiration())
                .signWith(SignatureAlgorithm.HS512,secret)
                .compact();
    }
    /*
    从JWT token 获取负载
    */
    private Claims getClaimsFromToken(String token){
        Claims claims = null;
        try {
            claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return claims;
    }

    /*
   生成过期时间的方法
    */
    private Date generateExpiration(){
        return new Date(System.currentTimeMillis() + expiration * 1000);
    }

    /*
  从jwt中获取过期时间
   */
    private Date getExpiration(String token){
        Claims claims = getClaimsFromToken(token);
        return claims.getExpiration();
    }
    /*
     判断token是否过期
  */
    private boolean isIsLive(String token){
        Date expiration = getExpiration(token);
        //Date1.before(Date2)，当Date1小于Date2时，返回TRUE，当大于等于时，返回false；
        return expiration.before(new Date());
    }

    /*
    从token中获取用户名
 */
    public String getUserName(String token){
        String username = null;
        try {
            Claims claims = getClaimsFromToken(token);
            username = claims.getSubject();
        } catch (Exception e) {
            username = null;
        }
        return username;
    }
    /*
         判断token是否有效
      */
    public boolean isActive(String token, UserDetails userDetails){
        String userName = getUserName(token);
        return userName.equals(userDetails.getUsername()) &&
                (!isIsLive(token));
    }
    /*
        根据用户信息生成token
     */
    public String  generateToken( UserDetails userDetails){
        Map<String,Object> map = new HashMap<>();
        map.put(CLAIM_KEY_CREATED,new Date());
        map.put(CLAIM_KEY_USERNAME,userDetails.getUsername());
        return generateToken(map);
    }
    /*
       判断token是否可以刷新
    */
    public boolean  canReFlush( String token){
       return !isIsLive(token);
    }
    /*
       刷新token
    */
    public String  reFreshToken (String token){
        Claims claimsFromToken = getClaimsFromToken(token);
        claimsFromToken.put(CLAIM_KEY_CREATED,new Date());
        return generateToken(claimsFromToken);
    }

}
